using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Controls.Templates;
using Avalonia.Markup.Xaml;
using Humanizer.Configuration;
using Microsoft.DotNet.PlatformAbstractions;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using ReactiveUI;
using SageKing.Extensions;
using SukiUI.Controls;
using SukiUI.Dialogs;
using SukiUI.Toasts;

namespace SageKing.Desktop;

public class App : Avalonia.Application
{
    private IServiceProvider? _provider;
      

    public override void Initialize()
    {
        AvaloniaXamlLoader.Load(this);
        _provider = ConfigureServices();
    }

    public override void OnFrameworkInitializationCompleted()
    {
        if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
        {
            var viewLocator = _provider?.GetRequiredService<IDataTemplate>();
            var mainViewModel = _provider?.GetRequiredService<MainDesktopVM>();
            var mainView = _provider?.GetRequiredService<SukiWindow>();
            mainView.DataContext = mainViewModel;
            mainView.WindowState = WindowState.Maximized;
            desktop.MainWindow = mainView;
        }

        base.OnFrameworkInitializationCompleted();
    }

    private ServiceProvider ConfigureServices()
    {

        var services = new ServiceCollection();

        //// Views
        services.AddSingleton<SukiWindow, MainDesktop>();

        //// Services
        var viewLocator = Current?.DataTemplates.First(x => x is UI.SKAvaloniaUI.Common.ViewLocator);
        if (viewLocator is not null)
            services.AddSingleton(viewLocator);


        var configbuilder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory());

        configbuilder.AddConfigurationJsonFiles(default);

        var configuration = configbuilder.Build();

        //add AddSageKing
        services.AddSageKing(sk => {

            sk.UseIceMediatR(o => o.MediatRServiceConfiguration += a =>
            {
                a.RegisterServicesFromAssemblies(typeof(Program).Assembly);
            });

            sk.UseIceRPC(o => o.ClientTypeDicOptions += options =>
            {
                configuration.Bind(options);
            });

            sk.UseIceRPCServer(o => o.IceRPCServerOptions += options =>
            {
                configuration.Bind(options);
            });

            sk.UseIceRPCClient(o => o.IceRPCClientListOptions += options =>
            {
                configuration.Bind(options);
            });

            //add ice application
            sk.UseSageKingApplicationIceRPC();

            sk.UseSKAvaloniaUI();
        });


        //// ViewModels
        services.AddSingleton<MainWindowVM>();
        services.AddSingleton<MainDesktopVM>();

        var types = AppDomain.CurrentDomain.GetAssemblies()
            .SelectMany(s => s.GetTypes())
            .Where(p => !p.IsAbstract && typeof(DesktopPageBase).IsAssignableFrom(p));
        foreach (var type in types)
            services.AddSingleton(typeof(DesktopPageBase), type);

        return services.BuildServiceProvider();
    }
}